import datetime
from sqlalchemy import ForeignKey, case, func
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import Mapped, mapped_column, relationship
from .base import Base
from .book import Book
from .student import Student


class ReceivingBook(Base):
    __tablename__ = 'receiving_books'

    student_id: Mapped[int] = mapped_column(ForeignKey(
        "students.id", ondelete="CASCADE"), primary_key=True)
    book_id: Mapped[int] = mapped_column(ForeignKey(
        "books.id", ondelete="CASCADE"), primary_key=True)

    date_of_issue: Mapped[datetime.date] = mapped_column(default=datetime.datetime.now())
    date_of_return: Mapped[datetime.date] = mapped_column(nullable=True)

    @hybrid_property
    def count_date_with_book(self):
        # количество дней, которые читатель держит/держал книгу у себя
        end_date = self.date_of_return or datetime.datetime.now()
        return (end_date - self.date_of_issue).days

    @count_date_with_book.expression
    def count_date_with_book(cls):
        end_date = case(
            (cls.date_of_return != None, cls.date_of_return),
            else_=func.now()
        )
        return func.julianday(end_date) - func.julianday(cls.date_of_issue)

    def __repr__(self):
        return f"{self.book_id} - {self.student_id} - {self.date_of_issue}"

    def __getitem__(self, item):
        return getattr(self, item)

    def to_json(self):
        return {c.first_name: f'{getattr(self, c.first_name)}' for c in self.__table__.columns}

    student_with_book: Mapped["Student"] = relationship(
        back_populates="student_receiving_books",
        cascade="all, delete",
        lazy="joined"
    )
    book: Mapped[Book] = relationship()
